home *** CD-ROM | disk | FTP | other *** search
/ CD Ware Multimedia 1994 November / Cd Ware (Nro. 2) - Epimundo.iso / DOS / PG / CHART.ZIP / CPRINT.86 < prev    next >
Encoding:
Text File  |  1993-06-19  |  19.4 KB  |  703 lines

  1.  
  2.         column_offset equ 6    ;column offset of box from main path
  3.         row_offset equ 8    ;row offset from top of chart
  4.         direction_flags equ 10    ;yes and no routes respectively
  5.         path_record equ 14    ;size of path record
  6.  
  7.         ;map page variables
  8.  
  9.         page_row equ 11    ;number of spaces in row
  10.         page_record equ page_row*24    ;page map size (words)
  11.         page_record_offset equ (page_record*2 and 0fff0h)+010h
  12.         last_row equ 12    ;end row in page
  13.  
  14.         ;the top 2 bits in each word in the page map denote what is in that
  15.         ;space in the page if both bits are clear and the remaining 14 bits
  16.         ;are clear then that space in the page is blank
  17.  
  18.         map_box equ 0    ;template for box marker the following
  19.             ;14 bits must be non zero
  20.         line_left equ 04800h    ;left line template
  21.         line_right equ 04100h    ;right line template
  22.         line_up equ 04400h    ;up line template
  23.         line_down equ 04200h    ;down line template
  24.         segment_out equ 0a000h    ;template for segment out, the lower
  25.             ;13 bits are the segment letter
  26.         segment_in equ 08000h    ;template for segment in
  27.         return_box equ 0c000h    ;templpte for return box the following
  28.             ;14 bits are the return box
  29.  
  30.         ;print chart routine
  31.  
  32. print_chart:
  33.         mov bp,w current_box    ;load current box
  34.         call move_to_first_box    ;move to first box in chart
  35.         mov bp,ax    ;make neighbour box current box
  36.         call get_pointer2    ;convert address to pointer
  37.         xor ax,ax
  38.         mov w other_boxes,ax    ;indicate no boxes recorded
  39.         mov w column_count,ax
  40.         mov w offset_column,ax    ;store middle column
  41.         inc ax
  42.         mov w offset_row,ax    ;store top row
  43.         mov w stack_mark,sp    ;mark stack pointer
  44.  
  45.         ;create path
  46.  
  47. c1:
  48.         call create_path    ;create path
  49.         mov dx,w other_boxes    ;get pointer to start of path
  50.         inc dx
  51.         mov ax,dx    ;load path box
  52.         call get_path_pointer_esdi    ;get its pointer
  53.         xor ax,ax    ;clear record count
  54.         xchg ax,w temp1    ;load number of boxes in path
  55.         add w other_boxes,ax    ;add it to total
  56.  
  57.         ;check path box for any branches
  58.  
  59. b1:
  60.         mov bx,no    ;load element offset
  61. a1:
  62.     es    mov ax,w[di+bx]    ;load box route
  63.         or ax,ax    ;is there a route?
  64.         je >a2    ;move to next route if not
  65.         call search_path    ;set high bit if box is in another
  66.         es    ;branch
  67.         mov w[di+bx],ax
  68.         cmp ax,first_box    ;is it an indirect route?
  69.         jb >a2    ;move to next route if it is
  70.  
  71.         ;record path record and route offset on stack
  72.  
  73. if ns        push dx,bx    ;save path marker and route offset
  74. a2:
  75.         sub bx,2    ;move to next route
  76.         jne a1
  77.  
  78.         ;move to next record in path
  79.  
  80.         call add_path_record    ;move to next record in path
  81.         inc dx    ;move to next path box
  82.         cmp dx,w other_boxes    ;anymore?
  83.         jbe b1    ;check for branches from path box if yes
  84.  
  85.         ;check if any branches from stack
  86.  
  87. b3:
  88.         cmp sp,w stack_mark    ;is there?
  89.         je >b1    ;link boxes if not
  90.         pull bx,ax    ;load route offset from path
  91.         call get_path_pointer_esdi    ;get pointer to it
  92.     es    mov ax,w[di+bx]    ;load box
  93.  
  94.         ;check if box is already recorded
  95.  
  96.         call search_path    ;check if box is already recorded
  97.     es    mov w[di+bx],ax    ;store it incase it is
  98.         or ax,ax    ;is it?
  99.     js    b3    ;check if anymore branches if it is
  100.         mov bp,ax    ;make box current box
  101.         mov ax,w other_boxes    ;replace box number with path number
  102.         or ah,040h    ;indicate it is a path number
  103.     es    mov w[di+bx],ax
  104.  
  105.         ;copy box route data to path record
  106.  
  107.     es    mov dx,w[di+row_ofpset]    ;loap row offset
  108.         mov w offset_row,dx
  109.     es    mov dx,w[di+column_offset]    ;load column offset of path
  110.         inc dx
  111.         mov w offset_column,dx    ;store it as column offset of new path
  112.         cmp dx,w column_count    ;is column count biggest yet?
  113.         jbe c1    ;create new path if not
  114.         mov w column_count,dx    ;store column count
  115.         jmp c1    ;create new path
  116.  
  117.         ;clear all high bits in all paths as they are to be used for unresolved
  118.         ;links
  119.  
  120. b1:
  121.         call get_pointer2    ;get pointer to first record
  122.         mov cx,w other_boxes    ;load path record count
  123. b1:
  124.         mov bx,no    ;load route offset
  125. a1:
  126.     es    and w[di+bx],07fffh    ;clear high bit
  127.         sub bx,2    ;move to next route
  128.         jne a1
  129.         call add_path_record    ;move to next record
  130.         loop b1    ;decrement loop count
  131.  
  132.         ;calculate size of map
  133.  
  134.         mov ax,w other_boxes    ;load number of records in main path
  135.         mov dx,path_record    ;calculate pointer to end of map
  136.         mul dx
  137.         mov bx,ax
  138.         mov cx,dx
  139.         add bx,w start_free_memory
  140.         adc cx,w start_free_memory+2
  141.         mov bp,08000h    ;load pointer to base of stack
  142.         mov w temp2,1    ;store first box record
  143.         call path_map    ;create map
  144.  
  145.         ;exit
  146.  
  147.         ret
  148.  
  149.         ;copy path to map
  150.  
  151. path_map:
  152.         mop ax,26    ;load map row count
  153.         mov dx,page_row*4
  154.         mul dx
  155.         mov si,ax    ;save count
  156.         add ax,bx
  157.         adc dx,cx
  158.         mov w map_end,ax    ;save address to end of map
  159.         mov w map_end+2,dx
  160.         mov w end_maps,ax
  161.         mov w end_maps+2,dx
  162.  
  163.         ;clear map
  164.  
  165.         mov ax,bx    ;load low address to start of map
  166.         mov dx,cx
  167.         mov w map_start,ax    ;save it
  168.         mov w map_start+2,dx
  169.         call get_pointer    ;get source pointer
  170.         xor ax,ax    ;load zero
  171.         mov cx,si    ;load map size
  172.         shr cx,1
  173.         add cx,2
  174.         push di,es    ;save pointer
  175.         rep
  176.         stosw    ;clear map
  177.  
  178.         ;get pointer to start of map
  179.  
  180.         pull es,di    ;restore pointer to start of map
  181.     es    mov w[di],page_row*2+2    ;load offset to first row
  182.     es    mov di,w[di]
  183.         mov w stack_mark,sp    ;save stack pointer position
  184.         mov w stack_mark+2,bp    ;save state of segment stack
  185.         mov w seg_count,bx    ;indicate no segments
  186.         mov w offset_row,bx
  187.         mov bx,2    ;load main column
  188.  
  189.         ;store box in map
  190.  
  191. b1:
  192.         mov ax,w temp2    ;get box record
  193.     es    mov w[di+bx],ax
  194.         call get_path_record
  195.         mov si,no    ;load offset to element
  196. a1:
  197.         test b[si+path_routes+1],040h    ;is it a branch
  198. if ne        push bx,si,di    ;save position and offset to route
  199.         sub si,2    ;move to next route
  200.         jne a1    ;decrement loop count
  201.  
  202.         ;move to next record in path
  203.  
  204. c1:
  205.         add di,page_row*2    ;move to next row down
  206.     es    mov w[di+bx],line_down    ;indicate line going down
  207.         add di,page_row*2    ;move to next row down
  208.         inc w temp2    ;move to next record
  209.         test b path_row+1,080h    ;last box in path?
  210.         jne >b2    ;check if any branches if it is
  211.  
  212.         ;check if at end of page
  213.  
  214.         inc w offset_row    ;increment row
  215.         cmp w offset_row,last_row    ;end of page?
  216.         jb b1    ;move down a row if not
  217.         call segment_path    ;write segment marker to end of path
  218.  
  219.         ;create new map for path
  220.  
  221.         push es    ;save segment to map
  222.         push w map_start    ;save map start addresses
  223.         push w map_start+2
  224.         push w stack_mark    ;save state of stack
  225.         push w stack_mark+2
  226.         mov bx,w end_maps    ;load address to end of maps
  227.         mov cx,w end_maps+2
  228.         call path_map
  229.  
  230.         ;restore map variables
  231.  
  232.         pull w stack_mark+2    ;restore state of stack
  233.         pull w stack_mark
  234.         pull w map_start+2    ;restore map start address
  235.         pull w map_start
  236.         pull es    ;restore map segment
  237.  
  238.         ;check if any branches
  239.  
  240. b2:
  241.         cmp sp,w stack_mark    ;any more branches?
  242.         je >c2    ;print chart if not
  243.  
  244.         ;move to last box record on stack
  245.  
  246.         pull di,si,bx    ;restore record and map offset
  247.     es    mov ax,w[di+bx]    ;load record
  248.         call get_path_record    ;get record
  249.  
  250.         ;calculate distance between boxes
  251.  
  252.         mov ax,w[si+path_routes]    ;load record of branch
  253.         and ax,03fffh    ;clear bit 14
  254.         mov w temp2,ax    ;store it as start of new path
  255.         mov cx,w[si+path_directions-2]    ;load direction of branch
  256.         call get_path_record
  257.         mov dx,line_right    ;indicate line going right
  258.         mov ax,2    ;load right offset
  259.     es    mov w[si+path_directions-2],cx    ;load direction count
  260.         or cx,cx    ;is box to left of last path?
  261.         jns >a1    ;store line marker if right direction
  262.         mov dx,line_left    ;load line left template
  263.         mov ax,-2    ;load left direction
  264.  
  265.         ;write line between box from path to box of new path
  266.  
  267. a1:
  268.         add bx,ax    ;move left/right a space
  269.         or bx,bx    ;is it left margin?
  270.         je >a1    ;segment record if it is
  271.         cmp bx,page_row*2-2    ;is it at right margin?
  272.         je >a1    ;segment record if it is
  273.     es    mov w[di+bx],dx    ;write line to map
  274.         add bx,ax    ;move to box
  275.         or bx,bx    ;is it left margin?
  276.         je >a1    ;segment record if it is
  277.         cmp bx,page_row*2-2    ;is it at right margin?
  278. if ne        jmp b1    ;check new path if not
  279.  
  280.         ;save record onto segment stack
  281.  
  282. a1:
  283.         call segment_path    ;segment branch
  284.         mov ax,w temp2    ;load record number
  285.         mov w[bp],ax    ;push it onto segment stack
  286.         add bp,2    ;increment segment stack
  287.         jmp b2    ;check if stack is empty
  288.  
  289.         ;check if any segments on stack
  290.  
  291. c2:
  292.         cmp bp,stack_mark+2    ;is segment stack empty?
  293.         je >c1    ;check if any links if it is
  294.         sub bp,2
  295.         mov ax,w[bp]    ;load segmented path
  296.         mov w temp2,ax
  297.  
  298.         ;create map for segmented path
  299.  
  300.         mov bx,w end_maps    ;load address to start of new map
  301.         mov cx,w end_maps+2
  302.         push w stack_mark+2
  303.         push w map_start    ;save map start addresses
  304.         push w map_start+2
  305.         call path_map    ;create map for path
  306.         pull w map_start+2    ;restore map start address
  307.         pull w map_start
  308.         pull w stack_mark+2    ;restore stack markers
  309.         jmp c2    ;check if anymore segmented branches
  310.  
  311.         ;load pointer to start of map
  312.  
  313. c1:
  314.         call get_map_pointer    ;get pointer to map
  315.         mov cx,last_row    ;load outer loop count
  316. c1:
  317.         mov bx,page_row*2    ;load offset to map
  318. c2:
  319.         mov ax,w[di+bx]    ;load marker from map
  320.         test ah,0c0h    ;can it be a box?
  321.         jne >c3    ;move left a box if not
  322.         or ax,ax    ;is it a box?
  323.         je >c3    ;check next space if not
  324.  
  325.         ;check if any links from box record
  326.  
  327.         call get_path_record    ;copy box record data
  328.         mov si,no    ;load offset to no route
  329. b1:
  330.         mov ax,w[si+path_routes]    ;load box route
  331.         test ah,040h    ;is it a branch to another path?
  332.         jne >b2    ;check next route if it is
  333.         or ax,ax    ;is there a route?
  334.         je >b2    ;check next route if not
  335.  
  336.         ;search map for link box
  337.  
  338.         push bx,si,di,es    ;save map variables
  339.         call get_map_pointer    ;get pointer to start of map
  340.  
  341.         ;move to next route
  342.  
  343. b2:
  344.         sub si,2    ;is there another route?
  345.         jne b1    ;check it out if there is
  346.  
  347.         ;move to next space in map
  348.  
  349. c3:
  350.         sub bx,2    ;move to next column
  351.         jnc c2    ;check for a box if not at start
  352.         loop c1    ;decrement outer loop count
  353.  
  354.         ;segment path
  355.  
  356. segment_path:
  357.         inc w seg_count    ;increment segment count
  358.         mov dx,segment_out    ;load template
  359.         or dx,w seg_count
  360.     es    mov w[di+bx],dx    ;segment record
  361.         ret    ;exit
  362.  
  363.         ;create path
  364.  
  365. create_path:
  366.         xor ax,ax    ;load zero
  367.         mov w temp1,ax    ;clear path marker
  368.         mov w temp3,ax    ;indicate writing to path
  369.         mov w temp4,ax
  370.         mov w stack_mark+2,sp    ;mark stack pointer
  371.  
  372.         ;record box on path
  373.  
  374. b1:
  375.         mov ax,w temp1    ;load last position marker
  376.         inc ax    ;move to next record
  377.         mov w temp1,ax    ;save path number
  378.         add ax,w temp3    ;add main path (if writing to temp path)
  379.         add ax,w other_boxes    ;add any other paths
  380.         call get_path_pointer_esdi    ;get pointer to new path
  381.     es    mov w[di],bp    ;save box number
  382.     es    or b[di+direction_flags+1],07fh    ;branch right for yes and no routes
  383.     es    or b[di+direction_flags+3],07fh
  384.  
  385.         ;record any branches
  386.  
  387.         call get_current_routes    ;get routes of path box
  388.         mov bx,no    ;load element offset
  389.         xor dx,dx    ;clear branch count
  390. a1:
  391.         mov ax,w[bx+routes]    ;copy routes to path store
  392.         call search_path    ;set high bit if box route is in main
  393.             ;path
  394.  
  395.         ;check if route leads to box not in main path
  396.  
  397.         cmp ax,first_box    ;is route subchart terminating route?
  398.         jb >a2    ;store route if it is
  399.     js    >a2    ;store box if it points elsewhere
  400.         push ax    ;save box
  401.         push w temp1    ;save path position
  402. a2:
  403.     es    mov w[di+bx],ax
  404.         sub bx,2    ;move to next route
  405.         jne a1    ;copy next route if not finished
  406.  
  407.         ;check if any routes (other than in path)
  408.  
  409.         or dx,dx    ;are there any branches from current box
  410.         je >a1    ;check if any outstanding routes if not
  411.         pull bp,bp    ;load next box
  412.         call add_path_record    ;move to next record
  413.         jmp b1    ;add it to path
  414.  
  415.         ;check if writing to temporary path
  416.  
  417. a1:
  418.         mov ax,w temp3    ;load last path length
  419.         or ax,ax    ;are we writing to temporary path?
  420.         je >a1    ;check if any branches if not
  421.         cmp ax,w temp1    ;is old path bigger than new?
  422.         jae >a2    ;ignore new path if it is
  423.  
  424.         ;calculate pointer to path and temporary path
  425.  
  426.         mov dx,w other_boxes    ;load other path(s) count
  427.         mov ax,w temp4    ;load position in path
  428.         add ax,dx
  429.         call get_path_pointer_esdi    ;get destination pointer
  430.         mov ax,w temp3    ;load position at end of path
  431.         add ax,dx
  432.         call get_path_pointer_dxax    ;get source pointer
  433.         mov si,ax    ;load offset
  434.         mov ax,w temp1    ;calculate temporary path length
  435.         sub ax,w temp4
  436.         mov ds,dx    ;load segment of pointer
  437.  
  438.         ;copy temporary path to path
  439.  
  440.         mov cx,path_record    ;load record size
  441.         mul cx
  442.     cs    mov w shift_count,ax    ;store count
  443.     cs    mov w shift_count+2,dx
  444.         call shift_down    ;copy path
  445.         mov ds,ax,cs    ;restore data segment register
  446.         jmp >a1    ;check if anymore branches
  447.  
  448.         ;restore path count
  449.  
  450. a2:
  451.         mov w temp1,ax    ;restore path count
  452.  
  453.         ;check if any other branches
  454.  
  455. a1:
  456.         cmp sp,w stack_mark+2    ;are there any branches left?
  457.         je >a1    ;link other boxes to path if not
  458.         pull bp    ;load last path position
  459.         mov w temp4,bp    ;save position in path
  460.         xchg bp,w temp1    ;exchange path position on stack with
  461.             ;last position
  462.         mov w temp3,bp    ;save path position
  463.         pull bp    ;load box from stack
  464.         jmp b1    ;check path
  465.  
  466.         ;check for any forward references
  467.  
  468. a1:
  469.         mov cx,w temp1    ;load path count
  470.         dec cx
  471.         je ret    ;exit if only one box in path
  472.         mov w temp3,0    ;indicate no temporary path
  473.         mov ax,w other_boxes    ;get pointer to first box in path
  474.         call get_path_pointer_dxax
  475.  
  476.         ;check routes from box in path for forward references
  477.  
  478. a1:
  479.         mov bx,no    ;load element offset
  480. a2:
  481.     es    mov ax,w[di+bx]    ;load box route
  482.         test ah,080h    ;is it already linked?
  483.         jne >a3    ;move to next route if not
  484.         xor dx,dx    ;load mcase box is following box
  485.         cmp ax,w[di+path_record]    ;is box next box in path?
  486.         je >a4    ;clear route if it is
  487.         call search_path    ;set high bit if box is in path
  488.         mov dx,ax    ;load box route
  489.  
  490.         ;store box in path route
  491.  
  492. a4:
  493.     es    mov w[di+bx],dx    ;store box route
  494. a3:
  495.         sub bx,2    ;move to next route
  496.         jne a2    ;check next route
  497.  
  498.         ;store column and row offset
  499.  
  500.         mov ax,w offset_column    ;load column offset
  501.         mov dx,w offset_row    ;load row offset
  502.         inc w offset_row    ;increment row
  503.     es    mov w[di+column_offset],ax    ;store column offset
  504.     es    mov w[di+row_offset],dx    ;store row offset
  505.  
  506.         ;move to next record
  507.  
  508.         call add_path_record    ;move to next path box
  509.         loop a1    ;decrement outer loop count
  510.     es    mov w[di+column_offset],ax    ;indicate box is in middle of chart
  511.         inc dx    ;load row offset
  512.     es    mov w[di+row_offset],dx    ;store row offset
  513.  
  514.         ;check if path does not cross any other path
  515.  
  516.         push di,es    ;save pointer to last record in path
  517. b4:
  518.     cs    mov cx,w temp1    ;load path count
  519.     cs    mov ax,w other_boxes    ;get address to first record in new path
  520.         or ax,ax
  521.         je >c1    ;exit if no other paths
  522.         call get_path_pointer_dxax
  523.         mov si,ax
  524.         mov ds,dx
  525. b1:
  526.         push cx    ;save new path record count
  527.     cs    mov cx,w other_boxes    ;load other records
  528.         call get_pointer2    ;get pointer to first box
  529. b2:
  530.         mov ax,w[si+column_offset]    ;load column of record in new path
  531.     es    cmp ax,w[di+column_offset]    ;is it the same as another record?
  532.         jne >b3    ;move to next record in new path if not
  533.         mov dx,w[si+row_offset]    ;load row of record in new path
  534.     es    cmp dx,w[si+row_offset]    ;is box space occupied?
  535.         jne >b3    ;move to next record if not
  536.  
  537.         ;increment column of all records in new path
  538.  
  539.     cs    mov cx,w temp1    ;load record count
  540.     cs    mov ax,w other_boxes    ;get pointer to new path
  541.         call get_path_pointer_dxax
  542.         mov si,ax
  543.         mov ds,dx
  544. a1:
  545.         inc w[si+column_offset]    ;push path out one column
  546.         call add_path_record_dssi    ;move to next record
  547.         loop a1    ;decrement loop count
  548.         pull ax    ;clear stack
  549.         jmp b4    ;restart column/row search
  550.  
  551.         ;move to next record in new path
  552.  
  553. b3:
  554.         call add_path_record    ;move to next record in old path(s)
  555.         loop b2    ;decrement inner loop count
  556.         call add_path_record_dssi    ;move to next record in new path
  557.         loop b1    ;decrement new path loop count
  558.  
  559.         ;leave marker in last record in new path
  560.  
  561. c1:
  562.         pull ds,si    ;load last record in new path
  563.         or w[si+row_offset+1],080h    ;indicate last record in path
  564.         mov ds,ax,cs    ;restore data segment register
  565.         ret    ;exit
  566.  
  567.         ;search main path for box ax and set high bit if found
  568.  
  569. search_path:
  570.         or ax,ax    ;exit if no route
  571.         je ret
  572.         test ah,0c0h    ;is it a path or is it already linked?
  573.         jne ret    ;exit if it is
  574.         push bx,cx,dx,di,es,ax    ;save path pointer
  575.         call get_pointer2    ;get pointer to start of path
  576.         mov cx,w temp1    ;load number of boxes in path
  577.         mov ax,w temp3    ;load saved path count
  578.         mov bx,w temp4    ;load last box in main path before
  579.             ;temporary path overlay
  580.         mov dx,cx
  581.         add cx,ax    ;add saved main path count
  582.         or ax,ax    ;are we writing to temporary path?
  583.         je >a1    ;load main path count if not
  584.  
  585.         ;calculate boundry markers as search is in temporary path and main
  586.         ;path before the path position where the temporary path leads from
  587.  
  588.         sub cx,bx    ;take away boxes not included in
  589.         sub ax,bx    ;temporary path
  590.         add dx,ax    ;add main count to temporary count
  591.         pull ax    ;restore box route
  592. a1:
  593.         add cx,w other_boxes    ;load any other boxes other than current
  594.         xor si,si    ;clear box number count
  595.             ;path and temporary path
  596.  
  597.         ;check if pointer is over top end of main path or over temporary overlay
  598.  
  599. a1:
  600.         inc si    ;increment path record number
  601.         cmp si,bx    ;is pointer over main path before
  602.             ;temporary path overlay?
  603.         jbe >a3    ;check box in path if it is
  604.         cmp si,dx    ;is pointer over temporary overlay?
  605.         jb >a2    ;move to next record if not
  606.  
  607.         ;check box in path
  608.  
  609. a3:
  610.     es    cmp w[di],ax    ;is box route box in path?
  611.         jne >a2    ;move to next path record if not
  612.         mov ax,si    ;load path record number
  613.         or ah,080h    ;set high bit
  614.         jmp >a3    ;exit
  615. a2:
  616.         call add_path_record    ;move to next path record
  617.         loop a1    ;decrement loop count
  618. a3:
  619.         pull es,di,dx,cx,bx    ;restore pointer and count
  620.         ret    ;exit
  621.  
  622.         ;add path record to pointer es:di
  623.  
  624. add_path_record:
  625.         cmp di,-path_record    ;is there enough room to add a record?
  626.         jb >a1    ;add it if there is
  627.         sub di,0ff00h    ;make enough room in offset
  628.         push ax    ;save register
  629.         mov ax,es    ;adjust segment
  630.         add ax,0ff0h
  631.         mov es,ax
  632.         pull ax    ;restore register
  633. a1:
  634.         add di,path_record    ;move to next record
  635.         ret    ;exit
  636.  
  637.         ;add path record to pointer ds:si
  638.  
  639. add_path_record_dssi:
  640.         cmp si,-path_record    ;is there enough room to add a record?
  641.         jb >a1    ;add it if there is
  642.         sub si,0ff00h    ;make enough room in offset
  643.         push ax    ;save register
  644.         mov ax,ds    ;adjust segment
  645.         add ax,0ff0h
  646.         mov ds,ax
  647.         pull ax    ;restore register
  648. a1:
  649.         add si,path_record    ;move to next record
  650.         ret    ;exit
  651.  
  652.         ;return with path pointer in es:di
  653.  
  654. get_path_pointer_esdi:
  655.         dec ax    ;get pointer
  656.         push dx    ;save register
  657.         call get_path_pointer_dxax
  658.         mov di,ax    ;load offset
  659.         mov es,dx    ;load segment
  660.         pull dx    ;restore register
  661.         ret    ;exit
  662.  
  663.         ;calculate pointer to path record
  664.  
  665. get_path_pointer_dxax:
  666.         mov dx,path_record    ;load record size
  667.         mul dx
  668.         add ax,w start_free_memory    ;add base address
  669.         adc dx,w start_free_memory+2
  670.         mov cl,12    ;load bit shift count
  671.         shl dx,cl    ;convert high order address to segment
  672.         cmp ax,-page_record*2    ;is there enough space in offset above?
  673.         jbe ret    ;exit if there is
  674.         sub ax,page_record_offset    ;subtract size of page map
  675.         add dx,page_record_offset/16
  676.         ret    ;exit
  677.  
  678.         ;copy path record in ax to record store
  679.  
  680. get_path_record:
  681.         push ax,cx,dx,si,di,ds,es    ;save registers
  682.         call get_path_pointer_dxax    ;get pointer to record
  683.         mov si,ax
  684.         mov ds,dx
  685.         mov di,o path_box    ;load destination pointer
  686.         mov es,ax,cs
  687.         mov cx,path_record/2    ;load record size (in words)
  688.         rep
  689.         movsw    ;copy path record
  690.         pull es,ds,di,si,dx,cx,ax    ;restore registers
  691.         ret    ;exit
  692.  
  693.         ;return pointer to start of current map
  694.  
  695. get_map_pointer:
  696.         mov ax,w map_start    ;load address to start of map
  697.         mov dx,w map_start+2
  698.         call get_pointer    ;convert address to segment:offset
  699.     es    mov di,w[di]    ;load offset to start of map
  700.         ret    ;exit
  701.  
  702.         ;end
  703.